package com.paul.web.response;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.paul.common.bean.ApiResult;
import com.paul.common.exception.ExceptionCode;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.annotation.Resource;

/**
 * @author ：zmk
 * @date ：Created in 2021/11/12 14:11
 * @description：
 */
@ControllerAdvice
public class ResponseDataHandler implements ResponseBodyAdvice<Object> {

    //这个方法表示对于哪些请求要执行beforeBodyWrite，返回true执行，返回false不执行
    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
//        System.out.println("=====执行ResponseDataHandler-supports=====");
        //使用此方法,則controller裡面的方法必須加上@ResponseBody才會返回true
        //return methodParameter.hasMethodAnnotation(ResponseBody.class);
        return true;
    }

    //对于返回的对象如果不是最终对象ResponseResult，则选包装一下
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
//        serverHttpResponse.setStatusCode(HttpStatus.OK);
//        HttpServletResponse response = (HttpServletResponse) serverHttpResponse;
//        response.setHeader("Access-Control-Allow-Origin","*");
//        response.setHeader("Access-Control-Allow-Credentials","true");
//        System.out.println("=====执行ResponseDataHandler-beforeBodyWrite=====");
        //加载swagger资源时，直接返回原始对象
        String uri = serverHttpRequest.getURI().toString();
        if (uri.contains("swagger") || uri.contains("api-docs")) {
            return o;
        }
        Gson gson = new Gson();
        ApiResult<Object> responseBean = new ApiResult<>(ExceptionCode.Normal.value(), "ok", o);
        if (methodParameter.hasMethodAnnotation(ExceptionHandler.class)) {
            return o;
        } else {
            if (o instanceof Resource || o instanceof ApiResult) {
                return o;
            } else if (o instanceof String) {
                //如果对象为String类型的，最后返回必须转成JsonString 不然会造成底层调用StringMessageConverter方法发生类型转换异常
                //建议在controller不要去返回String类型的值，包装成map再返回
                return gson.toJson(responseBean);
            } else {
                return responseBean;
            }
        }
    }
}
